package com.shopping.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shopping.dto.CartDTO;
import com.shopping.dto.CartItemDTO;

import com.shopping.entity.CartItem;
import com.shopping.entity.Order;
import com.shopping.entity.Product;
import com.shopping.entity.User;

import com.shopping.mapper.CartItemMapper;
import com.shopping.service.CartService;
import com.shopping.service.OrderService;
import com.shopping.service.ProductService;
import com.shopping.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import com.shopping.dto.ProductDTO;

@Service
@Slf4j
public class CartServiceImpl extends ServiceImpl<CartItemMapper, CartItem> implements CartService {

    @Autowired
    private ProductService productService;

    @Resource
    private UserService userService;

    @Resource
    private OrderService orderService;

    @Override
    public List<CartItem> getUserCart(Long userId) {
        try {
            if (userId == null) {
                throw new IllegalArgumentException("用户ID不能为空");
            }

            // 直接查询用户的购物车项
            List<CartItem> items = this.list(
                    new LambdaQueryWrapper<CartItem>()
                            .eq(CartItem::getUserId, userId)
            );

            // 加载商品信息
            if (items != null && !items.isEmpty()) {
                User user = userService.getById(userId); // 获取当前用户
                for (CartItem item : items) {
                    if (item.getProductId() != null) {
                        Product product = productService.getById(item.getProductId());
                        if (product != null) {
                            // 用DTO和折扣逻辑替换
                            ProductDTO productDTO = ((com.shopping.service.impl.ProductServiceImpl)productService).convertToDTO(product, user);
                            item.setProduct(productDTO);
                        }
                    }
                }
            }

            return items;
        } catch (Exception e) {
            log.error("获取购物车失败", e);
            throw new RuntimeException("获取购物车失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean addToCart(Long userId, Long productId, Integer quantity) {
        try {
            // 检查商品是否存在
            Product product = productService.getById(productId);
            if (product == null) {
                throw new IllegalArgumentException("商品不存在");
            }

            // 检查库存
            if (product.getStock() < quantity) {
                throw new IllegalArgumentException("商品库存不足");
            }

            // 检查购物车中是否已有该商品
            CartItem existingItem = this.getOne(
                    new LambdaQueryWrapper<CartItem>()
                            .eq(CartItem::getUserId, userId)
                            .eq(CartItem::getProductId, productId)
            );

            if (existingItem != null) {
                // 更新数量
                existingItem.setQuantity(existingItem.getQuantity() + quantity);
                existingItem.setUpdateTime(LocalDateTime.now());
                return this.updateById(existingItem);
            } else {
                // 添加新商品
                CartItem newItem = new CartItem();
                newItem.setUserId(userId);
                newItem.setProductId(productId);
                newItem.setQuantity(quantity);
                newItem.setCreateTime(LocalDateTime.now());
                newItem.setUpdateTime(LocalDateTime.now());
                return this.save(newItem);
            }
        } catch (Exception e) {
            log.error("添加购物车失败", e);
            throw new RuntimeException("添加购物车失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean updateCartItem(Long userId, Long cartItemId, Integer quantity) {
        try {
            // 查找购物车项
            CartItem item = this.getOne(
                    new LambdaQueryWrapper<CartItem>()
                            .eq(CartItem::getId, cartItemId)
                            .eq(CartItem::getUserId, userId)
            );

            if (item == null) {
                throw new IllegalArgumentException("购物车中不存在该商品");
            }

            // 检查商品是否存在
            Product product = productService.getById(item.getProductId());
            if (product == null) {
                throw new IllegalArgumentException("商品不存在");
            }

            // 检查库存
            if (product.getStock() < quantity) {
                throw new IllegalArgumentException("商品库存不足");
            }

            // 更新数量
            item.setQuantity(quantity);
            item.setUpdateTime(LocalDateTime.now());

            return this.updateById(item);
        } catch (Exception e) {
            log.error("更新购物车失败", e);
            throw new RuntimeException("更新购物车失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean removeCartItem(Long userId, Long cartItemId) {
        try {
            // 直接删除购物车项
            return this.remove(
                    new LambdaQueryWrapper<CartItem>()
                            .eq(CartItem::getId, cartItemId)
                            .eq(CartItem::getUserId, userId)
            );
        } catch (Exception e) {
            log.error("删除购物车商品失败", e);
            throw new RuntimeException("删除购物车商品失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean clearCart(Long userId) {
        try {
            // 直接删除用户的所有购物车项
            return this.remove(
                    new LambdaQueryWrapper<CartItem>()
                            .eq(CartItem::getUserId, userId)
            );
        } catch (Exception e) {
            log.error("清空购物车失败", e);
            throw new RuntimeException("清空购物车失败: " + e.getMessage());
        }
    }

    @Override
    public Integer getCartCount(Long userId) {
        List<CartItem> items = this.list(
                new LambdaQueryWrapper<CartItem>()
                        .eq(CartItem::getUserId, userId)
        );

        return items.stream()
                .mapToInt(CartItem::getQuantity)
                .sum();
    }

    @Override
    @Transactional
    public boolean batchRemoveCartItems(Long userId, List<Long> productIds) {
        try {
            return this.remove(
                    new LambdaQueryWrapper<CartItem>()
                            .eq(CartItem::getUserId, userId)
                            .in(CartItem::getProductId, productIds)
            );
        } catch (Exception e) {
            log.error("批量删除购物车商品失败", e);
            throw new RuntimeException("批量删除购物车商品失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean checkoutCart(Long userId, Map<String, Object> orderInfo) {
        try {
            // 获取用户的购物车项
            List<CartItem> cartItems = this.list(
                    new LambdaQueryWrapper<CartItem>()
                            .eq(CartItem::getUserId, userId)
            );

            if (cartItems.isEmpty()) {
                return false;
            }

            boolean allSuccess = true;

            // 为每个购物车项创建订单
            for (CartItem item : cartItems) {
                Product product = productService.getById(item.getProductId());
                if (product == null) {
                    continue;
                }

                // 检查库存
                if (product.getStock() < item.getQuantity()) {
                    allSuccess = false;
                    continue;
                }

                // 创建订单
                Order order = new Order();
                order.setUserId(userId);
                order.setProductId(item.getProductId());
                order.setQuantity(item.getQuantity());
                order.setTotalAmount(product.getPrice().multiply(new BigDecimal(item.getQuantity())));
                order.setOrderDate(LocalDateTime.now());

                // 设置订单信息
                if (orderInfo != null) {
                    order.setAddress((String) orderInfo.get("address"));
                    order.setContactPhone((String) orderInfo.get("contactPhone"));
                    order.setPaymentMethod(Order.PaymentMethod.valueOf((String) orderInfo.get("paymentMethod")));
                    order.setShippingMethod(Order.ShippingMethod.valueOf((String) orderInfo.get("shippingMethod")));
                    order.setRemarks((String) orderInfo.get("remarks"));
                }

                boolean orderSuccess = orderService.createOrder(order);
                if (!orderSuccess) {
                    allSuccess = false;
                }
            }

            // 如果所有订单创建成功，清空购物车
            if (allSuccess) {
                clearCart(userId);
            }

            return allSuccess;
        } catch (Exception e) {
            log.error("购物车结算失败", e);
            throw new RuntimeException("购物车结算失败: " + e.getMessage());
        }
    }

    @Override
    public Map<String, Object> getCartStatistics(Long userId) {
        List<CartItem> items = this.list(
                new LambdaQueryWrapper<CartItem>()
                        .eq(CartItem::getUserId, userId)
        );

        Map<String, Object> statistics = new HashMap<>();

        if (items.isEmpty()) {
            statistics.put("totalItems", 0);
            statistics.put("totalAmount", BigDecimal.ZERO);
            statistics.put("totalPoints", 0);
            return statistics;
        }

        int totalItems = 0;
        BigDecimal totalAmount = BigDecimal.ZERO;
        int totalPoints = 0;

        for (CartItem item : items) {
            Product product = productService.getById(item.getProductId());
            if (product != null) {
                totalItems += item.getQuantity();
                totalAmount = totalAmount.add(product.getPrice().multiply(new BigDecimal(item.getQuantity())));
                totalPoints += (product.getProductPoints() != null ? product.getProductPoints() : 0) * item.getQuantity();
            }
        }

        statistics.put("totalItems", totalItems);
        statistics.put("totalAmount", totalAmount);
        statistics.put("totalPoints", totalPoints);

        return statistics;
    }
}